﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json;
using FBroSharp;                    // ⚠️ #1 PRIORITY! FBroSharpControl, FBroSharpBrowserListControl
using FBroSharp.Lib;                // IFBroSharpBrowser, IFBroSharpFrame
using FBroSharp.Value;              // FBroSharpWindowsInfo, FBroSharpBrowserSetting
using FBroSharp.DataType;           // FBroSharpRequestContextSet, FBroSharpEventDisableControl
using FBroSharp.Const;              // FBroSharpTransitionType

namespace 指纹伪造浏览器
{
    public partial class Form1 : Form
    {
        private const string BROWSER_USER_FLAG = "fingerprint_browser";
        private IFBroSharpBrowser currentBrowser = null;
        private bool isBrowserCreated = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 初始化 UA 预设选择
            cmbPresetUA.SelectedIndex = 1; // 默认选择 Windows Chrome 120
            
            UpdateStatus("就绪 - 请创建浏览器");
            Console.WriteLine("Form1 加载完成");
        }

        #region 浏览器创建

        private void btnCreateBrowser_Click(object sender, EventArgs e)
        {
            try
            {
                if (isBrowserCreated)
                {
                    MessageBox.Show("浏览器已创建！如需重新创建，请先关闭当前浏览器。", 
                        "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                UpdateStatus("正在创建浏览器...");
                
                // 创建窗口信息（嵌入式浏览器）
                FBroSharpWindowsInfo windows_info = new FBroSharpWindowsInfo
                {
                    parent_window = panelBrowser.Handle,  // ⚠️ CRITICAL for embedded browser!
                    x = 0,
                    y = 0,
                    width = panelBrowser.Width,
                    height = panelBrowser.Height,
                    window_name = "指纹伪造浏览器"
                };

                // 创建浏览器事件回调类
                BrowserEvent browser_event = new BrowserEvent(this);

                // 创建浏览器（使用 default 而不是 null）
                if (FBroSharpControl.CreatBrowser(
                    txtUrl.Text, 
                    windows_info, 
                    default,      // browserset_info
                    default,      // request_context
                    default,      // extra_info
                    browser_event, 
                    default,      // ⚠️ CRITICAL! Use default for struct type
                    BROWSER_USER_FLAG))
                {
                    isBrowserCreated = true;
                    btnCreateBrowser.Enabled = false;
                    UpdateStatus("浏览器创建成功，正在初始化...");
                    Console.WriteLine("✅ 浏览器创建成功");
                }
                else
                {
                    UpdateStatus("浏览器创建失败");
                    MessageBox.Show("浏览器创建失败！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"创建失败: {ex.Message}");
                MessageBox.Show($"创建浏览器时发生错误：\n{ex.Message}", "错误", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                Console.WriteLine($"❌ 创建浏览器异常: {ex}");
            }
        }

        #endregion

        #region 浏览器导航

        private void btnBack_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = GetBrowser();
                if (browser != null && browser.IsValid)
                {
                    if (browser.CanGoBack())
                    {
                        browser.GoBack();
                        UpdateStatus("后退");
                    }
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"后退失败: {ex.Message}");
            }
        }

        private void btnForward_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = GetBrowser();
                if (browser != null && browser.IsValid)
                {
                    if (browser.CanGoForward())
                    {
                        browser.GoForward();
                        UpdateStatus("前进");
                    }
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"前进失败: {ex.Message}");
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = GetBrowser();
                if (browser != null && browser.IsValid)
                {
                    browser.Reload();
                    UpdateStatus("刷新页面");
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"刷新失败: {ex.Message}");
            }
        }

        private void btnNavigate_Click(object sender, EventArgs e)
        {
            NavigateToUrl();
        }

        private void txtUrl_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                NavigateToUrl();
                e.Handled = true;
            }
        }

        private void NavigateToUrl()
        {
            try
            {
                var browser = GetBrowser();
                if (browser != null && browser.IsValid)
                {
                    string url = txtUrl.Text.Trim();
                    if (!url.StartsWith("http://") && !url.StartsWith("https://"))
                    {
                        url = "https://" + url;
                    }
                    
                    var mainFrame = browser.GetMainFrame();
                    if (mainFrame != null && mainFrame.IsValid)
                    {
                        mainFrame.LoadURL(url);
                        UpdateStatus($"正在导航到: {url}");
                    }
                }
                else
                {
                    MessageBox.Show("请先创建浏览器！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"导航失败: {ex.Message}");
            }
        }

        #endregion

        #region 指纹配置

        private void cmbPresetUA_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cmbPresetUA.SelectedIndex)
            {
                case 1: // Windows Chrome 120
                    txtUserAgent.Text = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
                    txtScreenWidth.Text = "1920";
                    txtScreenHeight.Text = "1080";
                    txtDevicePixelRatio.Text = "1.0";
                    txtHardwareConcurrency.Text = "8";
                    txtDeviceMemory.Text = "8";
                    txtWebGLVendor.Text = "Google Inc. (Intel)";
                    txtWebGLRenderer.Text = "ANGLE (Intel, Intel(R) UHD Graphics 630)";
                    break;
                case 2: // Android Chrome 120
                    txtUserAgent.Text = "Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36";
                    txtScreenWidth.Text = "393";
                    txtScreenHeight.Text = "851";
                    txtDevicePixelRatio.Text = "2.75";
                    txtHardwareConcurrency.Text = "8";
                    txtDeviceMemory.Text = "4";
                    txtWebGLVendor.Text = "Qualcomm";
                    txtWebGLRenderer.Text = "Adreno (TM) 660";
                    break;
                case 3: // macOS Safari 17
                    txtUserAgent.Text = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15";
                    txtScreenWidth.Text = "1920";
                    txtScreenHeight.Text = "1080";
                    txtDevicePixelRatio.Text = "2.0";
                    txtHardwareConcurrency.Text = "8";
                    txtDeviceMemory.Text = "16";
                    txtWebGLVendor.Text = "Apple Inc.";
                    txtWebGLRenderer.Text = "Apple M1";
                    break;
                case 4: // Windows Edge 120
                    txtUserAgent.Text = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0";
                    txtScreenWidth.Text = "1920";
                    txtScreenHeight.Text = "1080";
                    txtDevicePixelRatio.Text = "1.0";
                    txtHardwareConcurrency.Text = "8";
                    txtDeviceMemory.Text = "8";
                    txtWebGLVendor.Text = "Google Inc. (NVIDIA)";
                    txtWebGLRenderer.Text = "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060)";
                    break;
                case 5: // Linux Firefox 120
                    txtUserAgent.Text = "Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0";
                    txtScreenWidth.Text = "1920";
                    txtScreenHeight.Text = "1080";
                    txtDevicePixelRatio.Text = "1.0";
                    txtHardwareConcurrency.Text = "8";
                    txtDeviceMemory.Text = "8";
                    txtWebGLVendor.Text = "X.Org";
                    txtWebGLRenderer.Text = "AMD Radeon RX 6700 XT";
                    break;
            }
        }

        private void btnApplyFingerprint_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = GetBrowser();
                if (browser == null || !browser.IsValid)
                {
                    MessageBox.Show("请先创建浏览器！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                UpdateStatus("正在应用指纹配置...");

                // 获取VIP控制器
                var vipControl = browser.GetVIPControl();
                if (vipControl == null || !vipControl.IsValid)
                {
                    MessageBox.Show("无法获取VIP控制器！请确认已安装VIP版本。", "错误", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 获取指纹控制器
                var fingerPrintControl = vipControl.GetFingerPrintControl();
                if (fingerPrintControl == null || !fingerPrintControl.IsValid)
                {
                    MessageBox.Show("无法获取指纹控制器！", "错误", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                List<string> appliedSettings = new List<string>();

                // 1. 设置 UserAgent
                if (!string.IsNullOrEmpty(txtUserAgent.Text))
                {
                    fingerPrintControl.SetVirUserAgent(txtUserAgent.Text, "zh-CN,zh;q=0.9,en;q=0.8", "Win32");
                    appliedSettings.Add("UserAgent");
                }

                // 2. 设置屏幕分辨率
                if (int.TryParse(txtScreenWidth.Text, out int screenWidth) && 
                    int.TryParse(txtScreenHeight.Text, out int screenHeight))
                {
                    fingerPrintControl.SetVirScreenHeightAndWidth(screenHeight, screenWidth);
                    appliedSettings.Add($"屏幕分辨率 ({screenWidth}x{screenHeight})");
                }

                // 3. 设置设备像素比
                if (double.TryParse(txtDevicePixelRatio.Text, out double devicePixelRatio))
                {
                    fingerPrintControl.SetVirDevicePixelRatio(devicePixelRatio);
                    appliedSettings.Add($"设备像素比 ({devicePixelRatio})");
                }

                // 4. 设置硬件并发数（CPU核心数）
                if (int.TryParse(txtHardwareConcurrency.Text, out int hardwareConcurrency))
                {
                    fingerPrintControl.SetVirHardwareConcurrency(hardwareConcurrency);
                    appliedSettings.Add($"CPU核心数 ({hardwareConcurrency})");
                }

                // 5. 设置设备内存
                if (int.TryParse(txtDeviceMemory.Text, out int deviceMemory))
                {
                    fingerPrintControl.SetVirDeviceMemory(deviceMemory);
                    appliedSettings.Add($"设备内存 ({deviceMemory}GB)");
                }

                // 6. 设置 WebGL 指纹
                if (!string.IsNullOrEmpty(txtWebGLVendor.Text))
                {
                    fingerPrintControl.SetVirWebglvendor(txtWebGLVendor.Text);
                    appliedSettings.Add("WebGL Vendor");
                }

                if (!string.IsNullOrEmpty(txtWebGLRenderer.Text))
                {
                    fingerPrintControl.SetVirWebglrenderer(txtWebGLRenderer.Text);
                    appliedSettings.Add("WebGL Renderer");
                }

                // 7. 设置时区
                if (int.TryParse(txtTimezoneHour.Text, out int timezoneHour))
                {
                    string timezoneName = txtTimezoneName.Text;
                    string timezoneStandard = txtTimezoneStandard.Text;
                    fingerPrintControl.SetVirTimeZone(timezoneHour, 0, timezoneName, timezoneStandard);
                    appliedSettings.Add($"时区 (UTC+{timezoneHour})");
                }

                // 8. 设置 Canvas 指纹噪声
                if (chkCanvasNoise.Checked)
                {
                    Random random = new Random();
                    int seed = random.Next(10000, 99999);
                    fingerPrintControl.SetCanvasFingerPrintRandom(5, 15, seed);
                    appliedSettings.Add("Canvas噪声");
                }

                // 9. 设置 WebGL 指纹噪声
                if (chkWebGLNoise.Checked)
                {
                    Random random = new Random();
                    int seed = random.Next(10000, 99999);
                    fingerPrintControl.SetWebGLFingerPrintRandom(5, 15, seed);
                    appliedSettings.Add("WebGL噪声");
                }

                // 10. 设置 Audio 指纹噪声
                if (chkAudioNoise.Checked)
                {
                    Random random = new Random();
                    int seed = random.Next(10000, 99999);
                    fingerPrintControl.SetAudioFingerPrintRandom(100, 200, seed);
                    appliedSettings.Add("Audio噪声");
                }

                // 11. 设置其他基础指纹
                fingerPrintControl.SetVirCookieEnabled(true);
                fingerPrintControl.SetVirJavaEnabled(false);
                fingerPrintControl.SetVirWebdriver(false);
                fingerPrintControl.SetVirOnLine(true);

                UpdateStatus($"✅ 指纹配置已应用 (共{appliedSettings.Count}项)");
                MessageBox.Show(
                    $"指纹配置已成功应用！\n\n已配置项目：\n{string.Join("\n", appliedSettings)}\n\n请刷新页面查看效果。",
                    "成功",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                Console.WriteLine($"✅ 指纹配置已应用: {string.Join(", ", appliedSettings)}");
            }
            catch (Exception ex)
            {
                UpdateStatus($"应用指纹失败: {ex.Message}");
                MessageBox.Show($"应用指纹配置时发生错误：\n{ex.Message}", "错误", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                Console.WriteLine($"❌ 应用指纹异常: {ex}");
            }
        }

        private void btnCheckFingerprint_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = GetBrowser();
                if (browser == null || !browser.IsValid)
                {
                    MessageBox.Show("请先创建浏览器！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // 导航到指纹检测网站
                var mainFrame = browser.GetMainFrame();
                if (mainFrame != null && mainFrame.IsValid)
                {
                    string[] testUrls = new string[]
                    {
                        "https://browserleaks.com/canvas",
                        "https://browserleaks.com/webgl",
                        "https://browserleaks.com/javascript",
                        "https://whoer.net/",
                        "https://pixelscan.net/"
                    };

                    var result = MessageBox.Show(
                        "选择要打开的指纹检测网站：\n\n" +
                        "是(Y) - BrowserLeaks Canvas\n" +
                        "否(N) - Whoer.net\n" +
                        "取消 - 不打开",
                        "选择检测网站",
                        MessageBoxButtons.YesNoCancel,
                        MessageBoxIcon.Question);

                    string selectedUrl = "";
                    if (result == DialogResult.Yes)
                    {
                        selectedUrl = testUrls[0];
                    }
                    else if (result == DialogResult.No)
                    {
                        selectedUrl = testUrls[3];
                    }
                    else
                    {
                        return;
                    }

                    txtUrl.Text = selectedUrl;
                    mainFrame.LoadURL(selectedUrl);
                    UpdateStatus($"正在打开指纹检测网站: {selectedUrl}");
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"打开检测网站失败: {ex.Message}");
                Console.WriteLine($"❌ 打开检测网站异常: {ex}");
            }
        }

        #endregion

        #region 配置保存/加载

        private void btnSaveConfig_Click(object sender, EventArgs e)
        {
            try
            {
                var config = new FingerprintConfig
                {
                    UserAgent = txtUserAgent.Text,
                    ScreenWidth = txtScreenWidth.Text,
                    ScreenHeight = txtScreenHeight.Text,
                    DevicePixelRatio = txtDevicePixelRatio.Text,
                    HardwareConcurrency = txtHardwareConcurrency.Text,
                    DeviceMemory = txtDeviceMemory.Text,
                    WebGLVendor = txtWebGLVendor.Text,
                    WebGLRenderer = txtWebGLRenderer.Text,
                    TimezoneHour = txtTimezoneHour.Text,
                    TimezoneName = txtTimezoneName.Text,
                    TimezoneStandard = txtTimezoneStandard.Text,
                    CanvasNoise = chkCanvasNoise.Checked,
                    WebGLNoise = chkWebGLNoise.Checked,
                    AudioNoise = chkAudioNoise.Checked
                };

                SaveFileDialog saveDialog = new SaveFileDialog
                {
                    Filter = "JSON 配置文件|*.json|所有文件|*.*",
                    Title = "保存指纹配置",
                    FileName = $"Fingerprint_{DateTime.Now:yyyyMMdd_HHmmss}.json"
                };

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    string json = JsonConvert.SerializeObject(config, Formatting.Indented);
                    File.WriteAllText(saveDialog.FileName, json);
                    UpdateStatus($"✅ 配置已保存: {Path.GetFileName(saveDialog.FileName)}");
                    MessageBox.Show("配置已成功保存！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存配置时发生错误：\n{ex.Message}", "错误", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnLoadConfig_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openDialog = new OpenFileDialog
                {
                    Filter = "JSON 配置文件|*.json|所有文件|*.*",
                    Title = "加载指纹配置"
                };

                if (openDialog.ShowDialog() == DialogResult.OK)
                {
                    string json = File.ReadAllText(openDialog.FileName);
                    var config = JsonConvert.DeserializeObject<FingerprintConfig>(json);

                    txtUserAgent.Text = config.UserAgent;
                    txtScreenWidth.Text = config.ScreenWidth;
                    txtScreenHeight.Text = config.ScreenHeight;
                    txtDevicePixelRatio.Text = config.DevicePixelRatio;
                    txtHardwareConcurrency.Text = config.HardwareConcurrency;
                    txtDeviceMemory.Text = config.DeviceMemory;
                    txtWebGLVendor.Text = config.WebGLVendor;
                    txtWebGLRenderer.Text = config.WebGLRenderer;
                    txtTimezoneHour.Text = config.TimezoneHour;
                    txtTimezoneName.Text = config.TimezoneName;
                    txtTimezoneStandard.Text = config.TimezoneStandard;
                    chkCanvasNoise.Checked = config.CanvasNoise;
                    chkWebGLNoise.Checked = config.WebGLNoise;
                    chkAudioNoise.Checked = config.AudioNoise;

                    cmbPresetUA.SelectedIndex = 0; // 设置为"自定义"
                    UpdateStatus($"✅ 配置已加载: {Path.GetFileName(openDialog.FileName)}");
                    MessageBox.Show("配置已成功加载！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载配置时发生错误：\n{ex.Message}", "错误", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region 辅助方法

        private IFBroSharpBrowser GetBrowser()
        {
            if (currentBrowser != null && currentBrowser.IsValid)
            {
                return currentBrowser;
            }

            currentBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
            return currentBrowser;
        }

        public void UpdateStatus(string status)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateStatus(status)));
                return;
            }

            lblStatus.Text = status;
        }

        public void UpdateUrl(string url)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateUrl(url)));
                return;
            }

            txtUrl.Text = url;
        }

        public void UpdateTitle(string title)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateTitle(title)));
                return;
            }

            this.Text = $"{title} - FBro 浏览器指纹伪造工具";
        }

        public void UpdateNavigationButtons(bool canGoBack, bool canGoForward)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateNavigationButtons(canGoBack, canGoForward)));
                return;
            }

            btnBack.Enabled = canGoBack;
            btnForward.Enabled = canGoForward;
        }

        #endregion

        #region 窗体事件

        private void Form1_Resize(object sender, EventArgs e)
        {
            ResizeEmbeddedBrowser();
        }

        private void ResizeEmbeddedBrowser()
        {
            try
            {
                var browser = GetBrowser();
                if (browser != null && browser.IsValid)
                {
                    // 调整浏览器大小以匹配容器
                    browser.MoveWindow(0, 0, panelBrowser.Width, panelBrowser.Height, true);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"调整浏览器大小失败: {ex.Message}");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                var browser = GetBrowser();
                if (browser != null && browser.IsValid)
                {
                    browser.CloseBrowser(true, true);
                    Console.WriteLine("浏览器已关闭");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"关闭浏览器时发生错误: {ex.Message}");
            }
        }

        #endregion
    }

    #region 指纹配置数据类

    public class FingerprintConfig
    {
        public string UserAgent { get; set; }
        public string ScreenWidth { get; set; }
        public string ScreenHeight { get; set; }
        public string DevicePixelRatio { get; set; }
        public string HardwareConcurrency { get; set; }
        public string DeviceMemory { get; set; }
        public string WebGLVendor { get; set; }
        public string WebGLRenderer { get; set; }
        public string TimezoneHour { get; set; }
        public string TimezoneName { get; set; }
        public string TimezoneStandard { get; set; }
        public bool CanvasNoise { get; set; }
        public bool WebGLNoise { get; set; }
        public bool AudioNoise { get; set; }
    }

    #endregion
}
